#include <cstdint>

#include <iostream>
#include <vector>

#include <CLI/CLI.hpp>

#include "d2_thread_pool.hpp"
#include "task_benchmark.hpp"

int main(int argc, char** argv)
{
    CLI::App app{"Thread Pool Benchmark"};

    int taskCount;
    bool showVersion { false };
    
    std::vector<int64_t> durationsRange; //任务执行时长，微秒数，-1 表示随机，此时需额外再提供随机范围，默认为 0 - 500 微秒

    TaskIndex taskIndex = TaskIndex::ExistingThreadPool;

    try
    {
        app.add_option("-i,--taskIndex", taskIndex, "Index of task to run")
            ->transform(CLI::CheckedTransformer(
                std::map<char const*, TaskIndex>
                {
                    {"Threads", TaskIndex::Threads},
                    {"ThreadPool", TaskIndex::ThreadPool},
                    {"ExistingThreadPool", TaskIndex::ExistingThreadPool}
                },
                CLI::ignore_case))
            ->default_val(TaskIndex::ExistingThreadPool);

        app.add_option("-c,--taskCount", taskCount, "Number of tasks to run")->default_val(1000);
        app.add_option("-d,--durations", durationsRange, 
                "Duration of task to run (microseconds)，[min, max]")->default_val(std::vector<int64_t>{0, 100});

        app.add_flag("-v,--version", showVersion, "Show version");
    }
    catch(CLI::ParseError &e)
    {
        std::cerr << "Error parsing command line arguments: " << e.what() << std::endl;
        return 1;
    }

    CLI11_PARSE(app, argc, argv);

    if (showVersion)
    {
        std::cout << "Version: " << 0.1 << "\n";

        #ifdef USE_MOVE_ONLY_FUNCTION_FOR_INTERNAL_TASK
        std::cout << "Using moveonly function for task" << std::endl;
        #else
        std::cout << "Using shared_ptr function for task" << std::endl;
        #endif
        
        return 0;
    }

    int64_t minDuration = -1, maxDuration = -1;

    if (durationsRange.size() == 1)
    {
        minDuration = maxDuration = durationsRange[0];
    }
    else if (durationsRange.size() == 2)
    {
        minDuration = durationsRange[0];
        maxDuration = durationsRange[1];
    }
    else
    {
        std::cerr << "Invalid duration range provided. Please provide either one or two values." << std::endl;
        return 1;
    }

    if (minDuration > maxDuration)
    {
        std::swap(minDuration, maxDuration);
    }

    std::cout << "Hardware_concurrency : " << std::thread::hardware_concurrency() << "\n";
    std::cout << "Task Count: " << taskCount << "\n";
    std::cout << "Duration (microseconds): " << "[" << minDuration << "," << maxDuration << "]\n";
    std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";

    // 调用 TestMain 函数
    TestMain(taskIndex, taskCount, minDuration, maxDuration);
}
